#include "graphics.hpp"
#include <iostream>

Graphics::Graphics() : window(nullptr), renderer(nullptr), isRunning(false) {}

Graphics::~Graphics() {
    close();
}

bool Graphics::init() {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cerr << "SDL初始化失败: " << SDL_GetError() << std::endl;
        return false;
    }

    window = SDL_CreateWindow("点线面数据显示",
                            SDL_WINDOWPOS_UNDEFINED,
                            SDL_WINDOWPOS_UNDEFINED,
                            WINDOW_WIDTH, WINDOW_HEIGHT,
                            SDL_WINDOW_SHOWN);
    if (!window) {
        std::cerr << "窗口创建失败: " << SDL_GetError() << std::endl;
        return false;
    }

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (!renderer) {
        std::cerr << "渲染器创建失败: " << SDL_GetError() << std::endl;
        return false;
    }

    isRunning = true;
    return true;
}

void Graphics::calculateScale(const Dataset& dataset) {
    if (dataset.allPoints.empty()) return;

    minX = maxX = dataset.allPoints[0].x;
    minY = maxY = dataset.allPoints[0].y;

    for (const auto& point : dataset.allPoints) {
        minX = std::min(minX, point.x);
        maxX = std::max(maxX, point.x);
        minY = std::min(minY, point.y);
        maxY = std::max(maxY, point.y);
    }

    double marginX = (maxX - minX) * 0.1;
    double marginY = (maxY - minY) * 0.1;
    scaleX = (WINDOW_WIDTH - 40) / (maxX - minX + 2 * marginX);
    scaleY = (WINDOW_HEIGHT - 40) / (maxY - minY + 2 * marginY);

    minX -= marginX;
    maxX += marginX;
    minY -= marginY;
    maxY += marginY;
}

void Graphics::transformPoint(double x, double y, int& screenX, int& screenY) {
    screenX = static_cast<int>(20 + (x - minX) * scaleX);
    screenY = static_cast<int>(WINDOW_HEIGHT - 20 - (y - minY) * scaleY);
}

void Graphics::drawDataset(const Dataset& dataset) {
    calculateScale(dataset);
    isRunning = true;

    while (isRunning) {
        // 处理所有待处理的事件
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    isRunning = false;
                    return;  // 直接返回
                case SDL_KEYDOWN:
                    if (event.key.keysym.sym == SDLK_ESCAPE || 
                        event.key.keysym.sym == SDLK_q) {
                        isRunning = false;
                        return;  // 直接返回
                    }
                    break;
                case SDL_WINDOWEVENT:
                    if (event.window.event == SDL_WINDOWEVENT_CLOSE) {
                        isRunning = false;
                        return;  // 直接返回
                    }
                    break;
            }
        }

        // 清空渲染器
        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        SDL_RenderClear(renderer);

        // 绘制多边形
        SDL_SetRenderDrawColor(renderer, 200, 200, 255, 255);
        for (const auto& polygon : dataset.polygons) {
            std::vector<SDL_Point> points(polygon.pointIndices.size());
            for (size_t i = 0; i < polygon.pointIndices.size(); ++i) {
                const Point& p = dataset.allPoints[polygon.pointIndices[i]];
                transformPoint(p.x, p.y, points[i].x, points[i].y);
            }
            SDL_RenderDrawLines(renderer, points.data(), points.size());
        }

        // 绘制折线
        SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
        for (const auto& polyline : dataset.polylines) {
            for (size_t i = 1; i < polyline.pointIndices.size(); ++i) {
                int x1, y1, x2, y2;
                const Point& p1 = dataset.allPoints[polyline.pointIndices[i-1]];
                const Point& p2 = dataset.allPoints[polyline.pointIndices[i]];
                transformPoint(p1.x, p1.y, x1, y1);
                transformPoint(p2.x, p2.y, x2, y2);
                SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
            }
        }

        // 绘制点
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        for (const auto& point : dataset.points) {
            int x, y;
            transformPoint(point.coord.x, point.coord.y, x, y);
            for (int dx = -2; dx <= 2; ++dx) {
                for (int dy = -2; dy <= 2; ++dy) {
                    if (dx*dx + dy*dy <= 4) {
                        SDL_RenderDrawPoint(renderer, x + dx, y + dy);
                    }
                }
            }
        }

        SDL_RenderPresent(renderer);
        SDL_Delay(16);  // 约60fps
    }
}

void Graphics::close() {
    isRunning = false;
    if (renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = nullptr;
    }
    if (window) {
        SDL_DestroyWindow(window);
        window = nullptr;
    }
    SDL_Quit();
} 